package moco.blatt8.clientserver;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {
	
	private final String EXIT = "EXIT";
	private final String ERROR = ">>#Error#<";
	private String eingabe_str = "";
	
	private final String HOST = "192.168.178.22"; // "192.168.178.22";
	private final int 	 PORT = 9997;
	private Socket server;
	private ObjectInputStream reader;
	private ObjectOutputStream writer;
	
	private EditText eingabe;
	private Button senden, abbr;
	private TextView ausgabe;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		eingabe = (EditText) findViewById(R.id.eingabe);
		senden 	= (Button) findViewById(R.id.senden);
		abbr 	= (Button) findViewById(R.id.abbr);
		ausgabe = (TextView) findViewById(R.id.ausgabe);
		
		abbr.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				_senden_an_server(EXIT);
			}
		});
		
		senden.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				eingabe_str = eingabe.getText().toString();
				_senden_an_server(eingabe_str);				
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}
	
	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		try {
			_verbindung_beenden();
		} catch (IOException e) {
		} catch (Exception e) {
		}
		_verbindung_aufbauen();
		return super.onMenuItemSelected(featureId, item);
	}
	
	@Override
	protected void onResume() {
		_verbindung_aufbauen();
		super.onResume();
	}
	
	@Override
	protected void onPause() {
		try {
			_verbindung_beenden();
		} catch (IOException e) {
			Log.e("DEBUG", "onPause: " + e.getMessage());
		} catch (Exception e) {
			Log.e("DEBUG", "onPause: " + e.getMessage());
		}
		super.onStop();
	}
	
	private void _senden_an_server(final String eingabe_str){
		new AsyncTask<String, String, String[]>() {

			@Override
			protected String[] doInBackground(String... params) {
				String ex = "", bestaetigung = "";
				try {
					
					if(eingabe_str.equalsIgnoreCase(EXIT)) {
						_verbindung_beenden();
						bestaetigung = "EXIT-Signal gesendet";
					} else {
						_writeObject(eingabe_str);
						Object o = reader.readObject();
						if(o != null)
							bestaetigung = (String) o;
					}
					return new String[] {"OK", bestaetigung};
					
				} catch (UnknownHostException e) {
					ex += e.getMessage() + ". ";
				} catch (IOException e) {
					ex += e.getMessage() + ". ";
				} catch (ClassNotFoundException e) {
					ex += e.getMessage() + ". ";
				} catch (Exception e) {
					ex += e.getMessage() + ". ";
				}
				
				return new String[] {ERROR, eingabe_str,ex};
			}
						
			@Override
			protected void onPostExecute(String[] result) {
				if(result != null && result[0].equalsIgnoreCase(ERROR)) {
					ausgabe.setText("\n> Fehler beim Senden von: " + result[1] + "\n");
				} else {
					ausgabe.setText("Server: " + result[1] + "\n");
				}
				eingabe.setText("");
				super.onPostExecute(result);
			}
		}.execute("");
	}
	
	private void _verbindung_aufbauen(){
		final Context c = this;
		new AsyncTask<String, String, String>(){
			ProgressDialog pd;
			protected void onPreExecute() {
				pd = new ProgressDialog(c);
				pd.setMessage("Verbindungsaufbau...");
				pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
				pd.show();
			};

			@Override
			protected String doInBackground(String... params) {
				try {
					server = new Socket(HOST, PORT);
					writer = new ObjectOutputStream(server.getOutputStream()); 
					reader = new ObjectInputStream(server.getInputStream());
				} catch (UnknownHostException e) {
					Log.e("DEBUG", ""+e.getStackTrace());
				} catch (IOException e) {
					Log.e("DEBUG", ""+e.getStackTrace());
				}
				return "";
			}
			
			protected void onCancelled() { pd.cancel(); };
			protected void onPostExecute(String result) { pd.cancel(); };
		}.execute("");
		
	}
	
	private void _verbindung_beenden() throws IOException, Exception{
		_writeObject(EXIT);
		_socket_schliessen();
	}
	
	private void _socket_schliessen() {
		try {
			writer.close();
			reader.close();
			server.close();
		} catch (IOException e) {}
	}
	
	private void _writeObject(Object text) throws IOException, Exception{
		if(writer == null || server == null) {
			throw new Exception("Keine Verbindung!");
		} else {
			writer.writeObject(text);
//			writer.write(CrLf);
			writer.flush();
		}
	}

}
